package com.lh.createData.controller;


import com.lh.createData.dto.ActionDto;
import com.lh.createData.model.*;
import com.lh.createData.model.InPutParam.*;
import com.lh.createData.myenum.TotalTypeEnum;
import com.lh.createData.service.*;
import com.lh.createData.unit.GetPropertiesClass;
import com.lh.createData.unit.LhClass;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 * @author ：梁昊，后端工程师：梁昊
 * @create 2021-07-20 12:51
 * @function
 * @editLog
 */
@RestController
@RequestMapping("/createController")
@Api(value = "定时、手动生成数据控制层", description = "系统运行态势平台定时、手动生成数据")
public class CreateController {
    @Autowired
    ActionService actionService;
    @Autowired
    GetPropertiesClass getPropertiesClass;
    @Autowired
    ColService colService;
    @Autowired
    MenuAuthorityService menuAuthorityService;
    @Autowired
    ProjectAndProductService projectAndProductService;
    @Autowired
    SystemUserService systemUserService;
    @Autowired
    ProductService productService;
    @Autowired
    MenuJumpTempService menuJumpTempService;
    @Autowired
    MenuJumpService menuJumpService;
    @Autowired
    ProjectService projectService;
    @Autowired
    UseTimeLenTempService useTimeLenTempService;
    @Autowired
    UseTimeLenService useTimeLenService;
    @Autowired
    MenuService menuService;
    @Autowired
    LogService logService;
    @Autowired
    ReportProjectTotalService reportProjectTotalService;
    @Autowired
    ProjAvgService projAvgService;


    @ApiOperation(value = "生成菜单加权平均值", notes = "/createController/V1/createDataAutoOrHand?token=token&beginDate=beginDate&endDate=endDate&count=count")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "项目token", dataType = "String")
            , @ApiImplicitParam(name = "beginDate", value = "数据所属期开始日期", dataType = "Date", required = true)
            , @ApiImplicitParam(name = "endDate", value = "数据所属期结束日期", dataType = "Date")
    })
    @PostMapping("/V1/createDataAutoOrHand")
    public int createDataAutoOrHand(
            @RequestParam(value = "token", required = false) String token
            , @RequestParam(value = "beginDate") @DateTimeFormat(pattern = "yyyy-MM-dd") Date beginDate
            , @RequestParam(value = "endDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate
    ) throws ParseException {
        if (endDate == null) {
            endDate = beginDate;
        }

        String logMessage = "菜单平均值数据";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        int resultCount = createActionHandTotalForInNum(token, beginDate, endDate);
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));
        return resultCount;
    }

    @ApiOperation(value = "生成所有统计数据[任务]", notes = "/createController/V1/createDateTotal?token=token&createDate=createDate&count=count")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "项目token", dataType = "String")
            , @ApiImplicitParam(name = "createDate", value = "数据所属期", dataType = "Date")
            , @ApiImplicitParam(name = "count", value = "已生成次数", dataType = "String", defaultValue = "-1")
    })
    @PostMapping("/V1/createDateTotal")
    public int createDateTotal(@RequestParam(value = "token", required = false) String token
            , @RequestParam(value = "createDate", required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") Date createDate
            , @RequestParam(value = "count", required = false, defaultValue = "-1") int count) throws UnsupportedEncodingException, ParseException {
        final String minDateText = "2021-07-01";
        final Date minDate = new SimpleDateFormat("yyyy-MM-dd").parse(minDateText);
        if (createDate.compareTo(minDate) < 0)
            return 0;
        final int deleteLogMonthCount = getPropertiesClass.getDeleteLogMonthCount();
        int sumCounter = 0, resultCount = 0;
        String logMessage = "用户统计";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = createUserCount(createDate);
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "项目与产品关系树";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = createProductTree(token, createDate);
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "菜单树";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = createMenuTree(token, createDate);
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "项目月度加权平均值";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = selectProjAvgByProjectAndTime(token, createDate, "月");
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "项目季加权平均值";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = selectProjAvgByProjectAndTime(token, createDate, "季");
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "项目年度加权平均值";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = selectProjAvgByProjectAndTime(token, createDate, "年");
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "产品信息";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = insertProduct(token, createDate);
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "用户使用时长";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = createUseTimeLength(token, createDate, count);
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "界面跳转";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = selectActionForUserTimeAndJump(token, createDate, count);
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount));

        logMessage = "项目实施率统计";
        logService.insertSystemLog(String.format("开始生成%s", logMessage));
        resultCount = createReportProjectTotal(createDate);
        sumCounter += resultCount;
        logService.insertSystemLog(String.format("生成完成%s：%d条数据", logMessage, resultCount), deleteLogMonthCount);

        String tableName = "menu_authority";
        String fieldName = "createTime";
        sumCounter += clearHistoryData(tableName, fieldName, deleteLogMonthCount);

        tableName = "menu_jump";
        sumCounter += clearHistoryData(tableName, fieldName, deleteLogMonthCount);

        tableName = "sys_log";
        sumCounter += clearHistoryData(tableName, fieldName, deleteLogMonthCount);

        tableName = "vou_menu";
        sumCounter += clearHistoryData(tableName, fieldName, deleteLogMonthCount);

        tableName = "vou_useTimeLength";
        sumCounter += clearHistoryData(tableName, fieldName, deleteLogMonthCount);

        tableName = "report_projectTotal";
        fieldName = "createDate";
        sumCounter += clearHistoryData(tableName, fieldName, deleteLogMonthCount);

        tableName = "vou_projAvg";
        fieldName = "currentDate";
        sumCounter += clearHistoryData(tableName, fieldName, deleteLogMonthCount);
        return sumCounter;
    }

    private CurrentDateIndexModel getCurrentDateIndex(Date createTime, int index, String totalType) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(createTime);
        switch (totalType) {
            case "月":
                calendar.add(Calendar.MONTH, -1);
                index = 0;
                break;
            case "季":
                calendar.add(Calendar.MONTH, -3);
                index = index < 2 ? 4 : (index - 1);
                break;
            case "半年":
                calendar.add(Calendar.MONTH, -6);
                index = index < 2 ? 2 : 1;
                break;
            case "年":
                calendar.add(Calendar.MONTH, -12);
                index = 0;
                break;
        }
        CurrentDateIndexModel currentDateIndexModel = new CurrentDateIndexModel();
        currentDateIndexModel.setDate(calendar.getTime());
        currentDateIndexModel.setNumIndex(index);
        calendar.clear();
        return currentDateIndexModel;
    }

    private int selectProjAvgByProjectAndTime(String token
            , Date createDate
            , String totalType
    ) throws ParseException {
        BeginEndModel beginEndModel;
        int weekIndex = -1;
        boolean executeSign = false;
        switch (totalType) {
            case "月":
                executeSign = this.getMonth(createDate);
                break;
            case "季":
                weekIndex = this.getSean(createDate);
                executeSign = weekIndex > 0;
                break;
            case "半年":
                weekIndex = this.getHalfYear(createDate);
                executeSign = weekIndex > 0;
                break;
            case "年":
                executeSign = this.getYear(createDate);
                break;
        }
        if (!executeSign)
            return 0;

        beginEndModel = getBeginEnd(createDate, totalType);
        if (beginEndModel == null)
            return 0;
        String projectId = null;
        if (token != null) {
            projectId = projectService.selectProjectIdByToken(token);
            if (projectId == null) {
                return 0;
            }
        }

        ProjAvgReportInParam projAvgReportInParam = new ProjAvgReportInParam();
        if (projectId != null) {
            projAvgReportInParam.setProjectCode(projectId);
        }
        final CurrentDateIndexModel currentDateIndex = getCurrentDateIndex(createDate, weekIndex, totalType);

        projAvgReportInParam.setBeginDate(beginEndModel.getBeginDate());
        projAvgReportInParam.setEndDate(beginEndModel.getEndDate());
        final List<ProjAvgReportModel> projAvgReportModels = projAvgService.selectProjAvgByProjectAndTime(projAvgReportInParam);
        int insertCount = 0;
        if (!projAvgReportModels.isEmpty()) {
            for (ProjAvgReportModel projAvgReportModel :
                    projAvgReportModels) {
                insertCount += insertAvg(projAvgReportModel.getProjectCode()
                        , totalType
                        , currentDateIndex.getDate()
                        , currentDateIndex.getNumIndex()
                        , projAvgReportModel.getScore()
                        , projAvgReportModel.getWeight()
                        , projAvgReportModel.getWeightNum());
            }
            projAvgReportModels.clear();
        }
        return insertCount;
    }

    private int insertAvg(String proCode
            , String totalType
            , Date currentDate
            , int weekIndex
            , BigDecimal weightNumSum
            , BigDecimal weightSum
            , BigDecimal totalValue) {
        if (totalValue == null) {
            totalValue = BigDecimal.valueOf(0);
        }
        ProjAvgInParam projAvgInParam = new ProjAvgInParam();
        String mainKey = LhClass.getDoorPictureKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
        projAvgInParam.setId(mainKey);
        projAvgInParam.setProCode(proCode);
        projAvgInParam.setTotalType(totalType);
        TotalTypeEnum totalTypeEnum;
        switch (totalType) {
            case "日":
                totalTypeEnum = TotalTypeEnum.DAY;
                break;
            case "月":
                totalTypeEnum = TotalTypeEnum.MONTH;
                break;
            case "季":
                totalTypeEnum = TotalTypeEnum.SEASON;
                break;
            case "年":
                totalTypeEnum = TotalTypeEnum.YEAR;
                break;
            default:
                totalTypeEnum = TotalTypeEnum.DAY;
                break;
        }
        projAvgInParam.setCurrentDate(currentDate);
        projAvgInParam.setNumIndex(weekIndex);
        projAvgInParam.setWeightNumSum(weightNumSum);
        projAvgInParam.setWeightSum(weightSum);
        projAvgInParam.setTotalValue(totalValue);
        int resultCount = projAvgService.insertProjAvg(projAvgInParam, totalTypeEnum);

        return resultCount;
    }

    private int getHalfYear(Date createTime) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMdd");
        final String format = simpleDateFormat.format(createTime);
        int resultValue = 0;
        if (format.equals("0101"))
            resultValue = 1;
        if (format.equals("0601"))
            resultValue = 2;
        return resultValue;
    }

    private boolean getMonth(Date createTime) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd");
        final String format = simpleDateFormat.format(createTime);
        return format.equals("01");
    }

    private int getSean(Date createTime) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMdd");
        final String format = simpleDateFormat.format(createTime);
        int resultValue = 0;
        if (format.equals("0101"))
            resultValue = 1;
        if (format.equals("0401"))
            resultValue = 2;
        if (format.equals("0701"))
            resultValue = 3;
        if (format.equals("1001"))
            resultValue = 4;
        return resultValue;
    }

    private boolean getYear(Date createTime) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMdd");
        final String format = simpleDateFormat.format(createTime);
        return format.equals("0101");
    }

    private BeginEndModel getBeginEnd(Date createTime, String totalType) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM");
        Date beginDate = null, endDate;
        BeginEndModel beginEndModel = null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(createTime);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        endDate = calendar.getTime();
        String format;
        switch (totalType) {
            case "月":
                format = simpleDateFormat.format(calendar.getTime());
                beginDate = simpleDateFormat.parse(format + "-01");
                break;
            case "季":
                calendar.add(Calendar.MONTH, -3);
                format = simpleDateFormat.format(calendar.getTime());
                beginDate = simpleDateFormat.parse(format + "-01");
                break;
            case "半年":
                calendar.add(Calendar.MONTH, -6);
                format = simpleDateFormat.format(calendar.getTime());
                beginDate = simpleDateFormat.parse(format + "-01");
                break;
            case "年":
                calendar.add(Calendar.YEAR, -1);
                format = simpleDateFormat.format(calendar.getTime());
                beginDate = simpleDateFormat.parse(format + "-01");
                break;
        }
        calendar.clear();
        if (beginDate != null) {
            beginEndModel = new BeginEndModel();
            beginEndModel.setBeginDate(beginDate);
            beginEndModel.setEndDate(endDate);
        }
        return beginEndModel;
    }

    private int createReportProjectTotal(Date createDate) {
        int resultCount = 0;
        TotalProjectModel totalProjectModel = reportProjectTotalService.selectReportProjectTotal();
        if (totalProjectModel != null) {
            createDate = LhClass.getSameCurrentDate(createDate, -1);
            ReportProjectTotalInParam reportProjectTotalInParam = new ReportProjectTotalInParam();
            String mainKey = LhClass.getPowerKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
            reportProjectTotalInParam.setId(mainKey);
            reportProjectTotalInParam.setTotalCounter(totalProjectModel.getTotalCounter());
            reportProjectTotalInParam.setAlreadyExeCounter(totalProjectModel.getAlreadyExeCounter());
            reportProjectTotalInParam.setNoExeCounter(totalProjectModel.getNoExeCounter());
            reportProjectTotalInParam.setFinishCounter(totalProjectModel.getFinishCounter());
            reportProjectTotalInParam.setCreateDate(createDate);
            resultCount += reportProjectTotalService.insertReportProjectTotal(reportProjectTotalInParam);
        }
        return resultCount;
    }

    private int clearHistoryData(String tableName, String fieldName, int deleteLogMonthCount) {
        DeleteDataInParam deleteDataInParam = new DeleteDataInParam();
        deleteDataInParam.setTableName(tableName);
        deleteDataInParam.setFieldName(fieldName);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -1 * deleteLogMonthCount);
        deleteDataInParam.setDate(calendar.getTime());
        return actionService.clearHistoryData(deleteDataInParam);
    }

    private int insertProduct(String token, Date createDate) {
        int resultCounter = 0;
        createDate = LhClass.getSameCurrentDate(createDate, -1);
        String projectId = null;
        if (token != null) {
            projectId = projectService.selectProjectIdByToken(token);
            if (projectId == null) {
                return 0;
            }
        }
        final String separateId = new SimpleDateFormat("yyyyMM").format(createDate);
        ActionInParam actionInParam = new ActionInParam();
        actionInParam.setSeparateId(separateId);
        actionInParam.setProjectCode(projectId);
        actionInParam.setTableNo("_" + separateId);
        List<ActionProductModel> actionProductModels = actionService.selectProductGroupBy(actionInParam.getTableNo());
        if (!actionProductModels.isEmpty()) {
            for (ActionProductModel activeProductModel :
                    actionProductModels) {
                ProductInParam productInParam = new ProductInParam();
                productInParam.setId(activeProductModel.getProductCode());
                productInParam.setProductName(activeProductModel.getProductName());
                resultCounter += productService.insertProduct(productInParam);
            }
            actionProductModels.clear();
        }
        return resultCounter;
    }

    private boolean firstMonthSign(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd");
        final String day = simpleDateFormat.format(date);
        return !day.equals("01");
    }

    private int createMenuTree(String token, Date createDate
    ) {
        if (firstMonthSign(createDate))
            return -1;

        if (createDate == null) {
            createDate = LhClass.getSameCurrentDate(new Date(), -1);
        } else {
            createDate = LhClass.getSameCurrentDate(createDate, -1);
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
        int resultCounter = 0;
        final String separateId = simpleDateFormat.format(createDate);

        ActionInParam actionProduct = new ActionInParam();
        actionProduct.setSeparateId(separateId);
        String projectId = null;
        if (token != null) {
            projectId = projectService.selectProjectIdByToken(token);
            if (projectId == null) {
                return 0;
            }
        }
        actionProduct.setProjectCode(projectId);
        final List<ActionModel> productTrees = actionService.getProjectListGroupBy(actionProduct);
        if (!productTrees.isEmpty()) {
            MenuInParam menuInParam = new MenuInParam();
            menuInParam.setCreateTime(createDate);
            menuInParam.setProjectCode(projectId);
            menuService.deleteFromMenu(menuInParam);
            int productIndex = 0;
            for (ActionModel product :
                    productTrees) {
                String id = LhClass.getMainDataLineKey(Short.valueOf(getPropertiesClass.getPort()));
                menuInParam = new MenuInParam();
                menuInParam.setId(id);
                menuInParam.setProjectCode(product.getProjectCode());
                menuInParam.setProdCode(product.getProductCode());
                menuInParam.setProdName(product.getProductName());
                menuInParam.setClassIndex(0);
                menuInParam.setParaId("menu");
                menuInParam.setSortNo(productIndex++);
                menuInParam.setCreateTime(createDate);
                resultCounter += menuService.insertMenu(menuInParam);

                ActionInParam actionMenu = new ActionInParam();
                actionMenu.setSeparateId(separateId);
                actionMenu.setProjectCode(product.getProjectCode());
                actionMenu.setProductCode(product.getProductCode());
                final List<ActionModel> menuListGroupBy = actionService.getMenuListGroupBy(actionMenu);
                if (!menuListGroupBy.isEmpty()) {
                    int menuIndex = 0;
                    for (ActionModel menu :
                            menuListGroupBy) {
                        if (menu.getMenuCode().length() > 0) {
                            MenuInParam menuInParamMenu = new MenuInParam();
                            menuInParamMenu.setId(LhClass.getMainDataLineKey(Short.valueOf(getPropertiesClass.getPort())));
                            menuInParamMenu.setProjectCode(product.getProjectCode());
                            menuInParamMenu.setMenuCode(menu.getMenuCode());
                            menuInParamMenu.setMenuName(menu.getMenuName());
                            menuInParamMenu.setClassIndex(1);
                            menuInParamMenu.setParaId(id);
                            menuInParamMenu.setSortNo(menuIndex++);
                            menuInParamMenu.setCreateTime(createDate);
                            resultCounter += menuService.insertMenu(menuInParamMenu);
                        }
                    }
                    menuListGroupBy.clear();
                }
            }
            productTrees.clear();
            return resultCounter;
        } else
            return 0;
    }

    private int createProductTree(
            String token
            , Date createDate
    ) {
        if (firstMonthSign(createDate))
            return -1;

        String projectId = null;
        if (token != null) {
            projectId = projectService.selectProjectIdByToken(token);
            if (projectId == null) {
                return 0;
            }
        }
        if (createDate == null) {
            createDate = LhClass.getSameCurrentDay(new Date(), -1);
        } else {
            createDate = LhClass.getSameCurrentDay(createDate, -1);
        }

//        projectAndProductService.deleteProjectAndProduct();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");
        int resultCounter = 0;
        final String separateId = simpleDateFormat.format(createDate);
        ActionInParam actionInParam = new ActionInParam();
        actionInParam.setSeparateId(separateId);
        actionInParam.setProjectCode(projectId);
        final List<ActionModel> productTree = actionService.createProductTree(actionInParam);
        if (!productTree.isEmpty()) {
            int productIndex = 0;
            projectAndProductService.deleteProjectAndProduct();
            for (ActionModel actionModel :
                    productTree) {
                String paraId = "root";
                //得到产品节点
                ProjectAndProductInsertInParam projectAndProductInsertInParam = new ProjectAndProductInsertInParam();
                String mainKey = LhClass.getMainDataLineKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
                projectAndProductInsertInParam.setId(mainKey);
                projectAndProductInsertInParam.setProdCode(actionModel.getProductCode());
                projectAndProductInsertInParam.setProdName(actionModel.getProductName());
                projectAndProductInsertInParam.setParaId(paraId);
                projectAndProductInsertInParam.setSortNo(productIndex++);
                resultCounter += projectAndProductService.insertProjectAndProduct(projectAndProductInsertInParam);

                //得到项目节点
                ActionInParam actionInParamNode = new ActionInParam();
                actionInParamNode.setProjectCode(actionModel.getProductCode());
                actionInParamNode.setSeparateId(separateId);
                final List<ActionDto> projectNode = actionService.createProjectNode(actionInParamNode);
                if (!projectNode.isEmpty()) {
                    int projectIndex = 0;
                    for (ActionDto actionDto :
                            projectNode) {
                        paraId = actionModel.getProductCode();
                        projectAndProductInsertInParam = new ProjectAndProductInsertInParam();
                        mainKey = LhClass.getDoorPictureKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
                        projectAndProductInsertInParam.setId(mainKey);
                        projectAndProductInsertInParam.setProjCode(actionDto.getProjectCode());
                        projectAndProductInsertInParam.setProjName(actionDto.getProjName());
                        projectAndProductInsertInParam.setParaId(paraId);
                        projectAndProductInsertInParam.setSortNo(projectIndex++);
                        resultCounter += projectAndProductService.insertProjectAndProduct(projectAndProductInsertInParam);
                    }
                    projectNode.clear();
                }
            }
            productTree.clear();
        }
        return resultCounter;
    }

    private int selectActionForUserTimeAndJump(
            String token
            , Date getDataTime
            , int pageCounter) throws UnsupportedEncodingException {
        String projectId = null;
        if (token != null) {
            projectId = projectService.selectProjectIdByToken(token);
            if (projectId == null) {
                return 0;
            }
        }
        if (getDataTime == null) {
            getDataTime = LhClass.getDefaultDate();
        } else {
            getDataTime = LhClass.getSameCurrentDate(getDataTime, -1);
        }
        final List<ActionUserIniModel> actionUserIniModels = selectActiveLog(projectId, getDataTime, -128, -128, pageCounter);
        if (actionUserIniModels == null) {
            return 0;
        }
        int resultCount = 0;
        final String batchId = LhClass.getCompanyUseKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
        MenuJumpTempInParam menuJumpTempInParam = null;
        int index = 0;
        for (ActionUserIniModel actionUserIniModel :
                actionUserIniModels) {
            //更新次数
            String separateId = LhClass.getSeparateId(getDataTime);
            this.updateActionCounter(separateId, actionUserIniModel.getId()
                    , -128
                    , -128
                    , actionUserIniModel.getPageCounter() + 1);
            final boolean firstSign = index++ % 2 == 0 ? true : false;
            if (firstSign) {
                menuJumpTempInParam = new MenuJumpTempInParam();
                String mainKey = LhClass.getCompanyUseKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
                menuJumpTempInParam.setId(mainKey);
                menuJumpTempInParam.setProjectCode(actionUserIniModel.getProjectCode());
                menuJumpTempInParam.setProjectName(actionUserIniModel.getProjectName());
                menuJumpTempInParam.setSourceMenuCode(actionUserIniModel.getMenuCode());
                menuJumpTempInParam.setSourceMenuName(actionUserIniModel.getMenuName());
                menuJumpTempInParam.setBatchId(batchId);
            } else {
                if (menuJumpTempInParam != null) {
                    if (!menuJumpTempInParam.getSourceMenuCode().equals(actionUserIniModel.getMenuCode())) {
                        menuJumpTempInParam.setDecMenuCode(actionUserIniModel.getMenuCode());
                        menuJumpTempInParam.setDecMenuName(actionUserIniModel.getMenuName());
                        resultCount += menuJumpTempService.insertMenuJumpTemp(menuJumpTempInParam);
                    }
                }
            }
        }
        if (resultCount == 0)
            return 0;
        resultCount = 0;
        List<MenuJumpTempSelectModel> menuJumpTempSelectModels = menuJumpTempService.selectMenuJumpTempByBatchId(batchId);
        menuJumpTempService.deleteMenuJumpTempByBatchId(menuJumpTempInParam);
        final int MaxCount = menuJumpTempSelectModels.size() > getPropertiesClass.getPageJumpMax() ?
                getPropertiesClass.getPageJumpMax() : menuJumpTempSelectModels.size();
        MenuJumpInParam menuJumpInParam = new MenuJumpInParam();
        menuJumpInParam.setCreateTime(getDataTime);
        if (projectId != null) {
            menuJumpInParam.setProjectCode(projectId);
        }
        menuJumpService.deleteMenuByCreateTime(menuJumpInParam);
        for (int i = 0; i < MaxCount; i++) {
            final MenuJumpTempSelectModel menuJumpTempSelectModel = menuJumpTempSelectModels.get(i);
            menuJumpInParam = new MenuJumpInParam();
            menuJumpInParam.setId(LhClass.getPowerKey(Short.valueOf(getPropertiesClass.getPort())));
            menuJumpInParam.setProjectCode(menuJumpTempSelectModel.getProjectCode());
            menuJumpInParam.setProjectName(menuJumpTempSelectModel.getProjectName());
            menuJumpInParam.setSourceMenuCode(menuJumpTempSelectModel.getSourceMenuCode());
            menuJumpInParam.setSourceMenuName(menuJumpTempSelectModel.getSourceMenuName());
            menuJumpInParam.setDecMenuCode(menuJumpTempSelectModel.getDecMenuCode());
            menuJumpInParam.setDecMenuName(menuJumpTempSelectModel.getDecMenuName());
            menuJumpInParam.setJumpCount(menuJumpTempSelectModel.getCounter());
            menuJumpInParam.setCreateTime(getDataTime);
            resultCount += menuJumpService.insertMenuJump(menuJumpInParam);
        }
        return resultCount;
    }

    @ApiOperation(value = "增加日志", notes = "/createController/V1/insertSystemLog?content=content")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "content", value = "日志内容", dataType = "String", required = true)
    })
    @PostMapping("/V1/insertSystemLog")
    public int insertSystemLog(@RequestParam(value = "content") String content) {
        return logService.insertSystemLog(content);
    }

    private int createUserCount(Date createDate) {
        if (createDate == null) {
            createDate = LhClass.getSameCurrentDate(new Date(), -1);
        } else {
            createDate = LhClass.getSameCurrentDate(createDate, -1);
        }
//        if (firstMonthSign(createDate)) {
//            return -1;
//        }
        final String separateId = LhClass.getSeparateId(createDate);
        ActionUserCountInParam actionUserCountInParam = new ActionUserCountInParam();
//        actionUserCountInParam.setGetDataTime(createDate);
        actionUserCountInParam.setSeparateId(separateId);
        final List<ActionUserCountModel> actionUserCountModels = actionService.createUserCount(actionUserCountInParam);
        int resultCount = 0;
        if (!actionUserCountModels.isEmpty()) {
            for (ActionUserCountModel actionUserCountModel :
                    actionUserCountModels) {
                SystemUserInParam systemUserInParam = new SystemUserInParam();
                String mainKey = LhClass.getCompanyUseKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
                systemUserInParam.setId(mainKey);
                systemUserInParam.setProjectCode(actionUserCountModel.getProjectId());
                systemUserInParam.setCreateDate(createDate);
                systemUserInParam.setTotalValue(actionUserCountModel.getTotalValue());
                resultCount += systemUserService.insertSystemUser(systemUserInParam);
            }
            actionUserCountModels.clear();
        }
        return resultCount;
    }

    private List<ActionUserIniModel> selectActiveLog(String projectCode
            , Date getDataTime
            , int arithCounter
            , int timeCounter
            , int pageCounter) throws UnsupportedEncodingException {
        if (projectCode != null) {
            projectCode = projectCode.trim();
            if (projectCode.getBytes("gbk").length > 100) {
                return null;
            }
        }
        String separateId = LhClass.getSeparateId(getDataTime);
        ActionUserIniInParam actionUserIniInParam = new ActionUserIniInParam();
        actionUserIniInParam.setProjectCode(projectCode);
        actionUserIniInParam.setGetDataTime(getDataTime);
        if (arithCounter > -128)
            actionUserIniInParam.setArithCounter(arithCounter);
        if (timeCounter > -128)
            actionUserIniInParam.setTimeCounter(timeCounter);
        if (pageCounter > -128)
            actionUserIniInParam.setPageCounter(pageCounter);
        actionUserIniInParam.setSeparateId(separateId);

        return actionService.selectActionForUserTimeAndJump(actionUserIniInParam);
    }

    private int createUseTimeLength(String token
            , Date createTime
            , int timeCounter
    ) throws UnsupportedEncodingException, ParseException {
        int resultValue = 0;
        if (createTime == null) {
            createTime = LhClass.getDefaultDate();
        } else {
            createTime = LhClass.getSameCurrentDate(createTime, -1);
        }
        final String userBeginTime = getPropertiesClass.getUserBeginTime();
        final String userEndTime = getPropertiesClass.getUserEndTime();
        String projectId = null;
        if (token != null) {
            projectId = projectService.selectProjectIdByToken(token);
            if (projectId == null) {
                return 0;
            }
        }
        final List<ActionUserIniModel> actionUserIniModels = selectActiveLog(projectId, createTime, -128, timeCounter, -128);
        final String batchId = LhClass.getCompanyUseKey(Short.valueOf(getPropertiesClass.getPort()));
        String separateId = LhClass.getSeparateId(createTime);
        if (!actionUserIniModels.isEmpty()) {
            Date beginTime = null;
            String userNameOld = null;
            UseTimeLenTempInParam useTimeLenTempInParam = null;
            for (ActionUserIniModel actionUserIniModel :
                    actionUserIniModels) {
                this.updateActionCounter(separateId, actionUserIniModel.getId()
                        , -128
                        , actionUserIniModel.getTimeCounter() + 1
                        , -128);
                final Date getDataTime = actionUserIniModel.getGetDataTime();
                if (beginTime == null) {
                    if (userNameOld != null) {
                        continue;
                    }
                    userNameOld = actionUserIniModel.getUserCode();
                    useTimeLenTempInParam = new UseTimeLenTempInParam();
                    useTimeLenTempInParam.setId(LhClass.getCompanyUseKey(Short.valueOf(getPropertiesClass.getPort())));
                    useTimeLenTempInParam.setBatchId(batchId);
                    useTimeLenTempInParam.setMenuId(actionUserIniModel.getMenuCode());
                    useTimeLenTempInParam.setMenuName(actionUserIniModel.getMenuName());
                    useTimeLenTempInParam.setProjectCode(actionUserIniModel.getProjectCode());
                    useTimeLenTempInParam.setProjectName(actionUserIniModel.getProjectName());
                    useTimeLenTempInParam.setUserId(actionUserIniModel.getUserCode());
                    useTimeLenTempInParam.setUserName(actionUserIniModel.getUserName());
                    useTimeLenTempInParam.setProductCode(actionUserIniModel.getProductCode());
                    useTimeLenTempInParam.setProductName(actionUserIniModel.getProductName());
                    beginTime = LhClass.getMaxMinDate(getDataTime, userBeginTime, true);
                } else {
                    if (userNameOld.equals(actionUserIniModel.getUserCode())) {
                        Date endTime = LhClass.getMaxMinDate(actionUserIniModel.getGetDataTime(), userEndTime, false);
                        final long compareTime = (endTime.getTime() - beginTime.getTime()) / 1000;
                        if (compareTime > 0) {
                            useTimeLenTempInParam.setUserTimeLength((int) compareTime);
                            resultValue += useTimeLenTempService.insertUseTimeLenTemp(useTimeLenTempInParam);
                        }
                    }
                    userNameOld = null;
                    beginTime = null;
                }
            }
            actionUserIniModels.clear();
        }
        if (resultValue > 0) {
            resultValue = 0;
            final List<UseTimeLenTempGroupModel> useTimeLenTempGroupModels = useTimeLenTempService.selectUseTimeLenTempGroupByBatchId(batchId);
            UseTimeLenTempInParam useTimeLenTempInParam = new UseTimeLenTempInParam();
            useTimeLenTempInParam.setBatchId(batchId);
            useTimeLenTempService.deleteUseTimeLenTemp(useTimeLenTempInParam);
            if (!useTimeLenTempGroupModels.isEmpty()) {
                UseTimeLenInParam useTimeLenInParam = new UseTimeLenInParam();
                useTimeLenInParam.setCreateTime(createTime);
                useTimeLenService.deleteUseTimeLenByCreateAndProject(useTimeLenInParam);
                for (UseTimeLenTempGroupModel useTimeLenTempGroupModel :
                        useTimeLenTempGroupModels) {
                    if (useTimeLenTempGroupModel.getUserTimeLength() > 0) {
                        String mainKey = LhClass.getDoorPictureKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
                        useTimeLenInParam.setId(mainKey);
                        useTimeLenInParam.setProjectCode(useTimeLenTempGroupModel.getProjectCode());
                        useTimeLenInParam.setProjectName(useTimeLenTempGroupModel.getProjectName());
                        useTimeLenInParam.setProductCode(useTimeLenTempGroupModel.getProductCode());
                        useTimeLenInParam.setProductName(useTimeLenTempGroupModel.getProductName());
                        useTimeLenInParam.setMenuId(useTimeLenTempGroupModel.getMenuId());
                        useTimeLenInParam.setMenuName(useTimeLenTempGroupModel.getMenuName());
                        useTimeLenInParam.setUserId(useTimeLenTempGroupModel.getUserId());
                        useTimeLenInParam.setUserName(useTimeLenTempGroupModel.getUserName());
                        useTimeLenInParam.setUserTimeLength(useTimeLenTempGroupModel.getUserTimeLength());
                        resultValue += useTimeLenService.insertUseTimeLen(useTimeLenInParam);
                    }
                }
                useTimeLenTempGroupModels.clear();
            }
        }
        return resultValue;
    }

    private int updateActionCounter(String separateId
            , String id
            , int arithCounter
            , int timeCounter
            , int pageCounter) throws UnsupportedEncodingException {
        return 0;
//        if (id != null) {
//            id = id.trim();
//            if (id.getBytes("gbk").length > 100) {
//                return -1;
//            }
//        }
//
//        ActionUpdateCountInParam actionUpdateCountInParam = new ActionUpdateCountInParam();
//        actionUpdateCountInParam.setId(id);
//        if (arithCounter > -128)
//            actionUpdateCountInParam.setArithCounter(arithCounter);
//        if (timeCounter > -128)
//            actionUpdateCountInParam.setTimeCounter(timeCounter);
//        if (pageCounter > -128)
//            actionUpdateCountInParam.setPageCounter(pageCounter);
//        actionUpdateCountInParam.setSeparateId(separateId);
//        int resultCount = actionService.updateActionCounter(actionUpdateCountInParam);
//
//        return resultCount;
    }

    private int createActionHandTotalForInNum(String token
            , Date beginTime
            , Date endTime) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        final String formatBegin = simpleDateFormat.format(beginTime);
        final String formatEnd = simpleDateFormat.format(endTime);
        beginTime = simpleDateFormat.parse(formatBegin);
        endTime = simpleDateFormat.parse(formatEnd);
        if (beginTime.compareTo(endTime) > 0) {
            return 0;
        }

        int insertCount = 0;
        Calendar calendar = new GregorianCalendar();
        while (beginTime.compareTo(endTime) < 0) {
            insertCount += createActionTotalForInNum(token, beginTime);
            calendar.setTime(beginTime);
            calendar.add(calendar.DAY_OF_MONTH, 1);
            beginTime = calendar.getTime();
        }
        calendar.clear();
        return insertCount;
    }

    private int createActionTotalForInNum(String token
            , Date createTime) throws ParseException {
        if (!getDateSign(createTime))
            return 0;
        int insertCount = 0;
        String projectId = null;
        if (token != null) {
            projectId = projectService.selectProjectIdByToken(token);
            if (projectId == null) {
                return 0;
            }
        }
        ActionInParam actionInParam = new ActionInParam();
        if (projectId != null) {
            actionInParam.setProjectCode(projectId);
        }
        actionInParam.setGetDateTime(createTime);
        final String separateId = new SimpleDateFormat("yyyyMM").format(createTime);
        actionInParam.setSeparateId(separateId);
        actionInParam.setArithCounter(1);
        final List<ActionModel> actionModels = actionService.selectActionTotalForInNum(actionInParam);
        if (!actionModels.isEmpty()) {
            //更新次数
//            actionService.updateActionTotalForInNum(actionInParam);
            MenuAuthorityInParam menuAuthorityInParam = new MenuAuthorityInParam();
            menuAuthorityInParam.setCreateTime(createTime);
            if (projectId != null) {
                menuAuthorityInParam.setProjectCode(actionInParam.getProjectCode());
            }
            menuAuthorityService.deleteMenuAuthorityByCreateTime(menuAuthorityInParam);
            for (ActionModel activeModel :
                    actionModels) {
                ColModel colModel = colService.selectColById(activeModel.getMenuCode());
                if (colModel == null) {
                    colModel = new ColModel();
                    colModel.setCaliCaption("一般");
                    colModel.setCalibration(0);
                    colModel.setWeight(BigDecimal.valueOf(0));
                }

                menuAuthorityInParam = new MenuAuthorityInParam();
                String mainKey = LhClass.getPowerKey(Short.valueOf(getPropertiesClass.getPort()));//这里引用架包中的生成主键方法
                menuAuthorityInParam.setId(mainKey);
                menuAuthorityInParam.setProjectCode(activeModel.getProjectCode());
                menuAuthorityInParam.setProjectName(activeModel.getProjectName());
                menuAuthorityInParam.setProductCode(activeModel.getProductCode());
                menuAuthorityInParam.setProductName(activeModel.getProductName());
                menuAuthorityInParam.setMenuCode(activeModel.getMenuCode());
                menuAuthorityInParam.setMenuName(activeModel.getMenuName());
                menuAuthorityInParam.setCounter(activeModel.getCounter());
                menuAuthorityInParam.setCaliCaption(colModel.getCaliCaption());
                menuAuthorityInParam.setCalibration(colModel.getCalibration());
                menuAuthorityInParam.setCreateTime(createTime);
                final BigDecimal score;
                final BigDecimal weightNum;
                if (colModel.getCalibration() > 0) {
                    score = BigDecimal.valueOf(activeModel.getCounter())
                            .multiply(BigDecimal.valueOf(100))
                            .divide(BigDecimal.valueOf(colModel.getCalibration()), 3, 1);
                    weightNum = score.multiply(colModel.getWeight())
                            .divide(BigDecimal.valueOf(100), 3, 1);
                } else {
                    score = BigDecimal.valueOf(0);
                    weightNum = score;
                }
                menuAuthorityInParam.setScore(score);
                menuAuthorityInParam.setWeight(colModel.getWeight());//权重
                menuAuthorityInParam.setWeightNum(weightNum);//权数
                //加权平均值 = 权数之和  /  权重之和
                insertCount += menuAuthorityService.insertMenuAuthority(menuAuthorityInParam);
            }
        }
        if (actionModels.size() > 0)
            actionModels.clear();
        return insertCount;
    }

    private boolean getDateSign(Date date) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        final Date minYearMonth = simpleDateFormat.parse(getPropertiesClass.getMinYearMonth());
        final Date maxYearMonth = simpleDateFormat.parse(getPropertiesClass.getMaxYearMonth());
        if (date.compareTo(minYearMonth) < 0 || date.compareTo(maxYearMonth) > 0)
            return false;
        else
            return true;
    }

}
